#include "RXBasicAspect/RXBasicAspectDef.h"
#include "RXBasicAspect/RXBasicAspectService.h"

#include "FrameComponent.h"
#include "FrameShadowNode.h"
#include "FrameAspect.h"
#include "FrameAspectDef.h"

class FrameNodeFactory:public ShadowNodeFactoryBase
{
	RXShadowNode* CreateNode() {
		return new FrameShadowNode();
	}
};

FrameAspect::FrameAspect()
{
	SetAspectInfo(RXAspectInfo(Aspects::AspectNames::FrameAspect, {Aspects::AspectNames::BasicAspect}));
}

FrameAspect::~FrameAspect()
{
}

RXECSDef::AspectJobList FrameAspect::CreateAspectJob(std::chrono::system_clock::duration delta)
{
	RXECSDef::AspectJobPtr frameJob = RXECSDef::AspectJob::CreateJob([=]() {
		auto delta_ = std::chrono::duration_cast<std::chrono::microseconds>(delta).count() / 1000.0;;
		frame_nodes->Foreach([&](RXShadowNode* node) {
			auto id = node->GetNodeId();
			const bool *r = basic_service->IsNodeGlobalEnabled(id);

			if (r && *r) {
				PostToFrontNode(id, new FrameAspect::FrameEvent(delta_));
			}

			return true;
			});
	}, {});

	return { frameJob };
}

void FrameAspect::AspectBegin()
{
	frame_nodes = new FrameNodeFactory();
	RegisterShadowFactory<FrameComponent>(frame_nodes);

	basic_service = dynamic_cast<RXBasicAspectService*>(AcquireAspectService(Aspects::AspectService::BasicAspectService));
}


FrameAspect::FrameEvent::FrameEvent(double time_delta):ThreadSafe::Event(-1)
{
	this->time_delta = time_delta;
}
